//
//  HLEDateConflictTool.m
//  HomeLinking
//
//  Created by hle1879 on 2021/8/2.
//  Copyright © 2021 HLE. All rights reserved.
//

#import "HLEDateConflictTool.h"
#import <YYCategories/YYCategories.h>
#import "NSDate+YSTools.h"

@implementation HLEDateConflictItem

-(instancetype)initWithStartDate:(NSDate *)startDate endDate:(NSDate*)endDate startTime:(NSDate*)startTime endTime:(NSDate*)endTime{
    return [self initWithStartDate:startDate endDate:endDate startTime:startTime endTime:endTime type:Date_Type_Default repeatTypes:@[]];
}

-(instancetype)initWithStartTime:(NSDate*)startTime endTime:(NSDate*)endTime repeatTypes:(NSArray*)repeatTypes{
    return [self initWithStartDate:nil endDate:nil startTime:startTime endTime:endTime type:Date_Type_Repeat repeatTypes:repeatTypes];
}

-(instancetype)initWithStartDate:(NSDate *)startDate endDate:(NSDate*)endDate startTime:(NSDate*)startTime endTime:(NSDate*)endTime type:(ConflictDateType)type repeatTypes:(NSArray*)repeatTypes{
    self = [super init];
    if (self) {
        self.startDate = startDate;
        self.endDate = endDate;
        self.startTime = startTime;
        self.endTime = endTime;
        self.type = type;
        self.repeatTypes = repeatTypes;
    }
    return self;
}

@end

@implementation HLEDateConflictTool

+(BOOL)timeIsConflict:(NSArray<HLEDateConflictItem*>*)dateArray forItem:(HLEDateConflictItem*)item{
    for (HLEDateConflictItem *obj in [self getCrossDayHistory:dateArray]) {
        NSArray *curCrossItems = [self getCrossItem:item];
        for (HLEDateConflictItem *curCrossItem in curCrossItems) {
            BOOL isConflict = [self isOverlap:obj curItem:curCrossItem];
            if (isConflict) {
                return YES;
            }
        }
    }
    return NO;
}

//判断是否重叠
+(BOOL)isOverlap:(HLEDateConflictItem*)perItem curItem:(HLEDateConflictItem*)curItem{
    BOOL isOverlap = NO;
    if (perItem.type == Date_Type_Default) {
        if (curItem.type == Date_Type_Default) {
            isOverlap = [self isOverlapForPlainAndPlain:perItem curItem:curItem];
        }else{
            isOverlap = [self isOverlapForPlainAndRepeat:perItem repeatItem:curItem];
        }
    }else{
        if (curItem.type == Date_Type_Default) {
            isOverlap = [self isOverlapForPlainAndRepeat:curItem repeatItem:perItem];
        }else{
            isOverlap = [self isOverlapForRepeatAndRepeat:perItem repeatItem:curItem];
        }
    }
    return isOverlap;
}

//判断2个普通时间端是否重叠
+(BOOL)isOverlapForPlainAndPlain:(HLEDateConflictItem*)perItem curItem:(HLEDateConflictItem*)curItem{
    NSDate *tempDate = perItem.startDate;
    while ([tempDate hle_compare:perItem.endDate] <= 0) {
        if ([curItem.endDate hle_compare:tempDate] < 0) {
            break;
        }
        if ([curItem.startDate hle_compare:tempDate] > 0) {
            tempDate = [self dateAfterDays:1 date:tempDate];
            continue;
        }

        NSDate *startTime1 = [self getNewDate:tempDate timeDate:perItem.startTime];
        NSDate *endTime1 = [self getNewDate:tempDate timeDate:perItem.endTime];
        
        NSDate *startTime2 = [self getNewDate:tempDate timeDate:curItem.startTime];
        NSDate *endTime2 = [self getNewDate:tempDate timeDate:curItem.endTime];
        
        BOOL isOverlap = [self isOverlap:startTime1 endDate1:endTime1 startDate2:startTime2 endDate2:endTime2];
        if (isOverlap) {
            return YES;
        }
        
        tempDate = [self dateAfterDays:1 date:tempDate];
    }
    return NO;
}

//判断一个普通时间和重复时间是否有冲突
+(BOOL)isOverlapForPlainAndRepeat:(HLEDateConflictItem*)plainItem repeatItem:(HLEDateConflictItem*)repeatItem{
    NSDate *tempDate = plainItem.startDate;
    while ([tempDate hle_compare:plainItem.endDate] <= 0) {
        RepeatType repeatType = [self getRepeatType:tempDate];
        if (![repeatItem.repeatTypes containsObject:@(repeatType)]) {
            tempDate = [self dateAfterDays:1 date:tempDate];
            continue;
        }
        NSDate *startTime1 = [self getNewDate:tempDate timeDate:plainItem.startTime];
        NSDate *endTime1 = [self getNewDate:tempDate timeDate:plainItem.endTime];
        
        NSDate *startTime2 = [self getNewDate:tempDate timeDate:repeatItem.startTime];
        NSDate *endTime2 = [self getNewDate:tempDate timeDate:repeatItem.endTime];
        
        BOOL isOverlap = [self isOverlap:startTime1 endDate1:endTime1 startDate2:startTime2 endDate2:endTime2];
        if (isOverlap) {
            return YES;
        }
        tempDate = [self dateAfterDays:1 date:tempDate];
    }
    return NO;
}

//判断一个普通时间和重复时间是否有冲突
+(BOOL)isOverlapForRepeatAndRepeat:(HLEDateConflictItem*)repeatItem1 repeatItem:(HLEDateConflictItem*)repeatItem2{
    for (NSNumber *type in repeatItem1.repeatTypes) {
        if (![repeatItem2.repeatTypes containsObject:type]) {
            continue;
        }
        BOOL isOverlap = [self isOverlap:repeatItem1.startTime endDate1:repeatItem1.endTime startDate2:repeatItem2.startTime endDate2:repeatItem2.endTime];
        if (isOverlap) {
            return YES;
        }
    }
    return NO;
}

//通过时间和日期的date组合成新的date
+(NSDate*)getNewDate:(NSDate*)date timeDate:(NSDate*)time{
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:@"yyyy-MM-dd"];
    NSString *dateStr = [formatter stringFromDate:date];
    [formatter setDateFormat:@"HH:mm:ss"];
    NSString *timeStr = [formatter stringFromDate:time];
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
    return [formatter dateFromString:[NSString stringWithFormat:@"%@ %@",dateStr,timeStr]];
}

//判断2个date是否重叠
+(BOOL)isOverlap:(NSDate*)startDate1 endDate1:(NSDate*)endDate1 startDate2:(NSDate*)startDate2 endDate2:(NSDate*)endDate2{
    return ([endDate1 compare:startDate2] > 0) && ([startDate1 compare:endDate2] < 0);
}

//N天之后的时间
+ (NSDate *)dateAfterDays:(int)days date:(NSDate*)date{
//    NSCalendar *calendar = [NSCalendar currentCalendar];
//    unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay;
//    NSDateComponents *components = [calendar components:unitFlags fromDate:date];
//    [components setDay:([components day]+days)];
//    return [calendar dateFromComponents:components];
    return [date dateByAddingDays:days];
}

//通过日期获取星期几
+(RepeatType)getRepeatType:(NSDate*)date{
    return date.weekday;
}

//跨天时间处理
+(NSArray<HLEDateConflictItem*>*)getCrossDayHistory:(NSArray<HLEDateConflictItem*>*)dataArray{
    NSMutableArray *tempArray = [[NSMutableArray alloc]init];
    for (HLEDateConflictItem* item in dataArray) {
        [tempArray addObjectsFromArray:[self getCrossItem:item]];
    }
    return tempArray;
}

+(NSArray*)getCrossItem:(HLEDateConflictItem*)item{
    NSMutableArray *tempArray = [[NSMutableArray alloc]init];
    if ([item.endTime compare:item.startTime] <= 0) {
        if (item.type == Date_Type_Default) {
            NSDate *startDate = [self dateAfterDays:1 date:item.startDate];
            NSDate *endDate = [self dateAfterDays:1 date:item.endDate];
            HLEDateConflictItem *item1 = [[HLEDateConflictItem alloc]initWithStartDate:item.startDate endDate:item.endDate startTime:item.startTime endTime:[self getDateByString:@"23:59:59" format:@"HH:mm:ss"]];
            HLEDateConflictItem *item2 = [[HLEDateConflictItem alloc]initWithStartDate:startDate endDate:endDate startTime:[self getDateByString:@"00:00:00" format:@"HH:mm:ss"] endTime:item.endTime];
            [tempArray addObject:item1];
            [tempArray addObject:item2];
        }else{
            HLEDateConflictItem *item1 = [[HLEDateConflictItem alloc]initWithStartTime:item.startTime endTime:[self getDateByString:@"23:59:59" format:@"HH:mm:ss"] repeatTypes:item.repeatTypes];
            HLEDateConflictItem *item2 = [[HLEDateConflictItem alloc]initWithStartTime:[self getDateByString:@"00:00:00" format:@"HH:mm:ss"] endTime:item.endTime repeatTypes:[self getCrossRepeatTypes:item.repeatTypes]];
            [tempArray addObject:item1];
            [tempArray addObject:item2];
        }
    }else{
        [tempArray addObject:item];
    }
    return tempArray;
}

//跨天重复类型处理
+(NSArray*)getCrossRepeatTypes:(NSArray*)repeatTypes{
    NSMutableArray *tempArray = [[NSMutableArray alloc]init];
    for (NSNumber *item in repeatTypes) {
        NSInteger type = item.intValue + 1;
        if (type > Saturday) {
            type = Sunday;
        }
        [tempArray addObject:@(type)];
    }
    return tempArray;
}

//时间字符串转时间
+(NSDate*)getDateByString:(NSString*)dateStr format:(NSString*)formatStr{
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    [formatter setDateFormat:formatStr];
    return [formatter dateFromString:dateStr];
}

@end
